package com.cmc.cloud.cmclink.doc.api.document;

import cn.hutool.core.bean.BeanUtil;
import com.cmc.cloud.cmclink.doc.api.document.emums.SiValidEnum;
import com.cmc.cloud.cmclink.doc.api.document.emums.SoDataSourceEnum;
import com.cmc.cloud.cmclink.doc.api.document.emums.SoStatusEnum;
import com.cmc.cloud.cmclink.doc.api.document.emums.ValidStatusEnum;
import com.cmc.cloud.cmclink.doc.api.document.rep.VgmCreateReqDto;
import com.cmc.cloud.cmclink.doc.api.document.rep.VgmEdiRespDto;
import com.cmc.cloud.cmclink.doc.api.document.rep.VgmRespDto;
import com.cmc.cloud.cmclink.doc.api.document.rep.VgmUpdateReqDto;
import com.cmc.cloud.cmclink.doc.api.document.req.*;
import com.cmc.cloud.cmclink.doc.api.document.req.si.VgmQueryInfoDto;
import com.cmc.cloud.cmclink.doc.constants.VgmCurrentPortConstants;
import com.cmc.cloud.cmclink.doc.constants.errorconstant.VgmErrorCodeConstants;
import com.cmc.cloud.cmclink.doc.convert.VgmConvert;
import com.cmc.cloud.cmclink.doc.entity.BlnoDO;
import com.cmc.cloud.cmclink.doc.entity.SoDO;
import com.cmc.cloud.cmclink.doc.entity.VgmDO;
import com.cmc.cloud.cmclink.doc.mapper.BlnoMapper;
import com.cmc.cloud.cmclink.doc.mapper.SoMapper;
import com.cmc.cloud.cmclink.doc.mapper.VgmMapper;
import com.cmc.cloud.cmclink.doc.service.VgmService;
import com.cmc.cloud.cmclink.doc.vo.vgm.*;
import com.cmes.framework.common.exception.util.ServiceExceptionUtil;
import com.cmes.framework.common.pojo.CommonResult;
import com.cmes.framework.common.pojo.PageParam;
import com.cmes.framework.common.pojo.PageResult;
import com.cmes.framework.mybatis.core.query.LambdaQueryWrapperX;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author lzp
 */
@RestController
@Validated
public class VgmRequestApiImpl implements VgmRequestApi {

    @Resource
    private VgmService vgmService;

    @Resource
    private VgmMapper vgmMapper;

    @Resource
    private BlnoMapper blnoMapper;

    @Resource
    private SoMapper soMapper;

    @Override
    public CommonResult<List<VgmRespDto>> getVgmInfoByEdi(VgmQueryEdiDto vgmQueryEdiDto) {
        VgmQueryEdiVO vgmQueryVo = BeanUtil.copyProperties(vgmQueryEdiDto, VgmQueryEdiVO.class);
        List<VgmDO> vgmDoList = vgmService.getVgmEdi(vgmQueryVo);
        List<VgmRespDto> vgmRespDtos = BeanUtil.copyToList(vgmDoList, VgmRespDto.class);
        //查询发货人的email  和telephone信息
        if (CollectionUtils.isNotEmpty(vgmRespDtos)) {
            vgmService.queryTelAndEmailInfo(vgmRespDtos);
        }
        return CommonResult.success(vgmRespDtos);
    }

    @Override
    public CommonResult<PageResult<VgmRespDto>> pageVgmInfo(VgmPageReqDto vgmPageQueryDto) {
        VgmPageReqVO request = BeanUtil.copyProperties(vgmPageQueryDto, VgmPageReqVO.class);
        List<SoDO> soList = soMapper.selectList(new LambdaQueryWrapperX<SoDO>()
                .eqIfPresent(SoDO::getBookingNo, vgmPageQueryDto.getBookingNo())
                .eqIfPresent(SoDO::getValidStatus, ValidStatusEnum.DEFAULT_VALID.getValue())
                .eqIfPresent(SoDO::getDataSource, SoDataSourceEnum.WEB.getValue())
                .neIfPresent(SoDO::getSoStatus, SoStatusEnum.BookingDraft.getValue()));
        if (CollectionUtils.isEmpty(soList)) {
            return CommonResult.success(new PageResult<VgmRespDto>(new ArrayList<>(), 0L));
        }
        Set<String> blNos = soList.stream().filter(p -> StringUtils.isNotEmpty(p.getBlNo())).map(SoDO::getBlNo).collect(Collectors.toSet());
        blNos.add(vgmPageQueryDto.getBlNo());
        request.setBlNos(blNos);
        LambdaQueryWrapperX<VgmDO> wrapperX = new LambdaQueryWrapperX<>();
        wrapperX.eqIfPresent(VgmDO::getVesselCode, request.getVesselCode());
        wrapperX.eqIfPresent(VgmDO::getVoyage, request.getVoyage());
        wrapperX.eqIfPresent(VgmDO::getCurrentPort, request.getCurrentPort());
        PageParam pageParam = new PageParam();
        pageParam.setPageNo(vgmPageQueryDto.getPageNo());
        pageParam.setPageSize(vgmPageQueryDto.getPageSize());
        PageResult<VgmDO> pageResult = vgmMapper.selectPage(pageParam, wrapperX);
        //PageResult<VgmDO> pageResult = vgmService.getVgmPage(request);
        List<VgmRespDto> results = VgmConvert.INSTANCE.convertVgmRespDto(pageResult.getList());
        return CommonResult.success(new PageResult<>(results, pageResult.getTotal()));
    }

    @Override
    public CommonResult<List<VgmRespDto>> getVgmInfo(VgmQueryDto vgmQueryDto) {
        VgmQueryVO vgmQueryVo = VgmConvert.INSTANCE.convert(vgmQueryDto);
        List<VgmDO> vgmDoList = vgmService.getVgm(vgmQueryVo);
        List<VgmRespDto> vgmRespDtos = VgmConvert.INSTANCE.convertVgmRespDto(vgmDoList);
        //查询发货人的email  和telephone信息
        if (CollectionUtils.isNotEmpty(vgmRespDtos)) {
            vgmService.queryTelAndEmailInfo(vgmRespDtos);
        }
        return CommonResult.success(vgmRespDtos);
    }

    @Override
    public CommonResult<List<VgmRespDto>> getVgmByCntrNos(VgmQueryInfoDto vgmQueryDto) {
        VgmQueryInfoVO request = BeanUtil.toBean(vgmQueryDto, VgmQueryInfoVO.class);
        List<VgmDO> vgmInfo = vgmService.getVgmInfo(request);
        List<VgmRespDto> vgmRespDtos = VgmConvert.INSTANCE.convertVgmRespDto(vgmInfo);

        return CommonResult.success(vgmRespDtos.stream().filter(e -> Objects.equals(SoDataSourceEnum.WEB.getValue(), e.getDataSource())).collect(Collectors.toList()));
    }

    @Override
    public CommonResult<List<VgmRespDto>> getVgmByBlnos(List<String> blnos) {
        List<VgmDO> vgmList = vgmService.getVgmByBlnos(blnos);
        return CommonResult.success(BeanUtil.copyToList(vgmList, VgmRespDto.class));
    }

    @Override
    public CommonResult<VgmRespDto> getVgmDetail(Long vgmId) {
        VgmDO vgmDo = vgmService.getVgmDetail(vgmId);
        return CommonResult.success(BeanUtil.toBean(vgmDo, VgmRespDto.class));
    }

    @Override
    public CommonResult<List<VgmImportReqDto>> importVgm(List<VgmImportReqDto> vgmImportReqDtoList, String vesselCode, String voyage, String port) {
        List<VgmImportReqVO> vos = VgmConvert.INSTANCE.convertVgmImportReqVo(vgmImportReqDtoList);
        List<VgmImportReqDto> vgmImportReqDtos = VgmConvert.INSTANCE.convertVgmImportReqDto(vgmService.importVgm(vos, vesselCode, voyage, port));
        return CommonResult.success(vgmImportReqDtos);
    }

    @Override
    public CommonResult<Void> createVgm(VgmCreateReqDto vgmCreateReqDto) {
        VgmCreateReqVO vgmCreateReqVo = VgmConvert.INSTANCE.convertVgmCreateReqVo(vgmCreateReqDto);
        vgmService.createVgm(vgmCreateReqVo);
        return null;
    }

    @Override
    public CommonResult<Void> updateVgm(VgmUpdateReqDto vgmUpdateReqDto) {
        VgmUpdateReqVO vgmUpdateReqVo = VgmConvert.INSTANCE.convertVgmUpdateReqVo(vgmUpdateReqDto);
        vgmUpdateReqVo.setOperationSource(vgmUpdateReqDto.getOperationSource());
        vgmService.updateVgm(vgmUpdateReqVo);
        return CommonResult.success();
    }

    @Override
    public CommonResult<Void> deleteVgm(Long id, String creator) {
        LambdaQueryWrapperX<VgmDO> lambdaQueryWrapperX = new LambdaQueryWrapperX<>();
        lambdaQueryWrapperX.eq(VgmDO::getId, id);
        //.eq(VgmDO::getCreator, creator);
        vgmMapper.delete(lambdaQueryWrapperX);
        return CommonResult.success();
    }

    @Override
    public CommonResult<VgmEdiRespDto> updateVgmEdi(VgmEdiReqAllDto vgmEdiReqAllDto) {
        Boolean flag = StringUtils.isBlank(vgmEdiReqAllDto.getVgmEdiReqDto().getBlNo()) && (StringUtils.isBlank(vgmEdiReqAllDto.getVgmEdiReqDto().getBlNo()) || StringUtils.isBlank(vgmEdiReqAllDto.getVgmEdiReqDto().getVoyage()));
        if (flag) {
            throw ServiceExceptionUtil.exception(VgmErrorCodeConstants.VGM_BLNO_VOYAGE_IS_NULL);
        }
        VgmEdiRespDto vgmEdiRespDto = new VgmEdiRespDto();
        vgmEdiRespDto.setMsg("SUCCESS");
        vgmEdiRespDto.setBlNo(vgmEdiReqAllDto.getVgmEdiReqDto().getBlNo());
        vgmEdiRespDto.setCntrNo(vgmEdiReqAllDto.getVgmEdiReqDto().getCntrNo());
        vgmEdiRespDto.setMsgId(vgmEdiReqAllDto.getMsgId());
        List<VgmDO> vgmDoList = new ArrayList<>(4);
        LambdaQueryWrapperX<VgmDO> vgmDoLambdaQueryWrapperX = new LambdaQueryWrapperX<>();
        /**
         * 青岛的港口不会传船名航次，新增时需要查询提单的船名航次信息,其他港口按照船名航次+箱号处理
         */
        if (VgmCurrentPortConstants.CURRENTPORT.contains(vgmEdiReqAllDto.getVgmEdiReqDto().getCurrentPort())) {
            vgmDoLambdaQueryWrapperX.eqIfPresent(VgmDO::getBlNo, vgmEdiReqAllDto.getVgmEdiReqDto().getBlNo())
                    .eqIfPresent(VgmDO::getCntrNo, vgmEdiReqAllDto.getVgmEdiReqDto().getCntrNo());
            vgmDoList = vgmMapper.selectList(vgmDoLambdaQueryWrapperX);
            if (CollectionUtils.isEmpty(vgmDoList)) {
                LambdaQueryWrapperX<BlnoDO> blnoDoLambdaQueryWrapperX = new LambdaQueryWrapperX<>();
                blnoDoLambdaQueryWrapperX.eq(BlnoDO::getBlNo, vgmEdiReqAllDto.getVgmEdiReqDto().getBlNo()).eq(BlnoDO::getValid, SiValidEnum.VALID.getValue()).last(" limit 1");
                BlnoDO blnoDO = blnoMapper.selectOne(blnoDoLambdaQueryWrapperX);
                if (Objects.isNull(blnoDO)) {
                    throw ServiceExceptionUtil.exception(VgmErrorCodeConstants.VGM_BLNO_IS_NOT_EXIST);
                }
                VgmCreateReqVO vgmDo = VgmConvert.INSTANCE.convertVgmCreateReqVo(vgmEdiReqAllDto.getVgmEdiReqDto());
                vgmDo.setBlNo(vgmEdiReqAllDto.getVgmEdiReqDto().getBlNo());
                vgmDo.setCntrNo(vgmEdiReqAllDto.getVgmEdiReqDto().getCntrNo());
                vgmDo.setVesselCode(blnoDO.getBkgVesselCode());
                vgmDo.setVoyage(blnoDO.getBkgVoyage());
                vgmDo.setUpdater(vgmEdiReqAllDto.getMsgId());
                vgmDo.setCreator(vgmEdiReqAllDto.getMsgId());
                vgmDo.setDataSource(SoDataSourceEnum.EDI.getValue());
                vgmService.createVgm(vgmDo);
            } else {
                VgmUpdateReqVO vgmUpdateReqVO = vgmUpdate(vgmDoList, vgmEdiReqAllDto);
                vgmService.updateVgm(vgmUpdateReqVO);
            }
        } else {
            vgmDoLambdaQueryWrapperX
                    .eqIfPresent(VgmDO::getCntrNo, vgmEdiReqAllDto.getVgmEdiReqDto().getCntrNo())
                    .eqIfPresent(VgmDO::getVoyage, vgmEdiReqAllDto.getVgmEdiReqDto().getVoyage())
                    .eqIfPresent(VgmDO::getVesselCode, vgmEdiReqAllDto.getVgmEdiReqDto().getVesselCode());
            vgmDoList = vgmMapper.selectList(vgmDoLambdaQueryWrapperX);
            if (CollectionUtils.isEmpty(vgmDoList)) {
                VgmCreateReqVO vgmDo = VgmConvert.INSTANCE.convertVgmCreateReqVo(vgmEdiReqAllDto.getVgmEdiReqDto());
                vgmDo.setUpdater(vgmEdiReqAllDto.getMsgId());
                vgmDo.setCreator(vgmEdiReqAllDto.getMsgId());
                vgmDo.setDataSource(SoDataSourceEnum.EDI.getValue());
            } else {
                VgmUpdateReqVO vgmUpdateReqVO = vgmUpdate(vgmDoList, vgmEdiReqAllDto);
                vgmService.updateVgm(vgmUpdateReqVO);
            }
        }
        return CommonResult.success(vgmEdiRespDto);
    }

    public VgmUpdateReqVO vgmUpdate(List<VgmDO> vgmDoList, VgmEdiReqAllDto vgmEdiReqAllDto) {
        VgmDO vgmDo = vgmDoList.get(0);
        VgmUpdateReqVO vgmUpdateReqVO = VgmConvert.INSTANCE.convertVgmUpdateReqVo(vgmDo);
        vgmUpdateReqVO.setWeight(vgmEdiReqAllDto.getVgmEdiReqDto().getWeight());
        vgmUpdateReqVO.setTypeCode(vgmEdiReqAllDto.getVgmEdiReqDto().getTypeCode());
        vgmUpdateReqVO.setAddress(vgmEdiReqAllDto.getVgmEdiReqDto().getAddress());
        vgmUpdateReqVO.setTime(vgmEdiReqAllDto.getVgmEdiReqDto().getTime());
        vgmUpdateReqVO.setSignature(vgmEdiReqAllDto.getVgmEdiReqDto().getSignature());
        vgmUpdateReqVO.setUpdater(vgmEdiReqAllDto.getMsgId());
        vgmUpdateReqVO.setId(vgmDo.getId());
        return vgmUpdateReqVO;
    }
}
